package com.example.project.aspect;

import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.time.LocalDateTime;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import com.example.project.annotation.IssueOperation;
import com.example.project.entity.Issue;
import com.example.project.entity.IssueOperationRecord;
import com.example.project.entity.Project;
import com.example.project.entity.User;
import com.example.project.service.CommonService;
import com.example.project.service.IssueOperationRecordService;
import com.example.project.service.IssueService;
import com.example.project.utils.ShiroUtils;

/**
 * 操作记录切面
 */
@Aspect
@Component
public class IssueOperationAspect {

	private static final Logger log = LoggerFactory.getLogger(IssueOperationAspect.class);

	@Autowired
	private IssueOperationRecordService operationRecordService;

	@Autowired
	private CommonService commonService;

	@Autowired
	private IssueService issueService;

	@Around("@annotation(com.example.project.annotation.IssueOperation)")
	public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
		// 获取方法签名
		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();

		// 获取注解
		IssueOperation annotation = method.getAnnotation(IssueOperation.class);

		// 执行原方法
		Object result = null;
		Exception exception = null;
		try {
			result = joinPoint.proceed();
			return result;
		} catch (Exception e) {
			exception = e;
			throw e;
		} finally {
			// 只有成功时才记录操作
			if (exception == null) {
				try {
					recordOperation(joinPoint, annotation, exception);
				} catch (Exception e) {
					log.error("记录操作失败", e);
				}
			}
		}
	}

	private void recordOperation(ProceedingJoinPoint joinPoint, IssueOperation annotation, Exception exception) {
		try {
			// 获取当前用户
			User currentUser = ShiroUtils.getSysUser();

			// 创建操作记录
			IssueOperationRecord record = new IssueOperationRecord();
			record.setIssueId(getIssueIdFromArgs(joinPoint.getArgs()));
			record.setOperatorId(currentUser.getUserId());
			record.setOperatorName(currentUser.getUserName());
			record.setOperationType(annotation.type());

			// 格式化操作内容
			String operationContent = formatOperationContent(annotation.value(), joinPoint.getArgs());
			record.setOperationContent(operationContent);

			// 设置操作时间
			record.setOperationTime(LocalDateTime.now());

			// 根据方法参数设置相关客户和需求信息
			setRelatedInfo(record, joinPoint.getArgs());

			// 保存记录
			operationRecordService.insertIssueOperationRecord(record);

			log.info("记录操作成功: {}", operationContent);
		} catch (Exception e) {
			log.error("记录操作异常", e);
		}
	}

	private Long getIssueIdFromArgs(Object[] args) {
		if (args == null || args.length == 0) {
			return null;
		}

		// 尝试从参数中获取Issue ID
		for (Object arg : args) {
			if (arg instanceof Long) {
				return (Long) arg;
			} else if (arg instanceof Integer) {
				return ((Integer) arg).longValue();
			}
		}
		return null;
	}

	private String formatOperationContent(String template, Object[] args) {
		if (template == null || template.isEmpty()) {
			return "";
		}

		try {
			return MessageFormat.format(template, args);
		} catch (Exception e) {
			log.warn("格式化操作内容失败: {}", template, e);
			return template;
		}
	}

	private void setRelatedInfo(IssueOperationRecord record, Object[] args) {
		// 从参数中提取Issue相关信息
		if (args != null && args.length > 0) {
			Long issueId = record.getIssueId();
			if (issueId != null) {
				try {
					// 通过CommonService获取Issue信息
					Issue issue = issueService.selectIssuesById(issueId);
					if (issue != null) {
						// 设置项目ID
						record.setProjectId(issue.getProjectId());

						// 获取客户名称
						if (issue.getProjectId() != null) {
							Project project = commonService.getProjectInfo(issue.getProjectId());
							if (project != null) {
								record.setCustomerName(project.getCustomerName());
							}
						}

						// 设置需求名称
						record.setRequirementName(issue.getSubject());
					}
				} catch (Exception e) {
					log.warn("获取Issue信息失败，issueId: {}", issueId, e);
				}
			}
		}
	}
}